package com.ruoyi.web.controller.airplane;

import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.ApiResponse;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.domain.TbAppVersion;
import com.ruoyi.system.domain.dto.DeviceHeartbeatRequestDTO;
import com.ruoyi.system.domain.dto.DownloadRequest;
import com.ruoyi.system.domain.dto.OfflinePackageInfo;
import com.ruoyi.system.domain.dto.TbDeviceAndInfoCreateDTO;
import com.ruoyi.system.domain.vo.DevicePendingTasksResponse;
import com.ruoyi.system.domain.vo.DeviceTaskResultResponse;
import com.ruoyi.system.domain.vo.TaskMessage;
import com.ruoyi.system.domain.vo.TaskStatusPost;
import com.ruoyi.system.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;

@Api(tags = "系统交互管理")
@RestController
@Slf4j
@RequestMapping("/interaction")
public class InteractionController extends BaseController {

    @Autowired
    private IInteractionService interactionService;

    @Autowired
    private IFileDownloadService fileDownloadService;

    @Autowired
    private IPendingTaskService pendingTaskService;

    @Autowired
    private IAPPOrDataPackageService appOrDataPackageService;

    @Autowired
    private OfflinePackageService offlinePackageService;


//    @Autowired
//    private DownloadService downloadService;

//    @ApiOperation("下载文件")
//    @GetMapping("/Download")
//    public ResponseEntity<StreamingResponseBody> downloadFile(
//            HttpServletRequest request,
//            @RequestParam String devSN,
//            @RequestParam String downloadToken) {
//
//        return downloadService.download(devSN, downloadToken, request);
//    }

    @ApiOperation("下载文件")
    @GetMapping("/Download")
    public ResponseEntity<StreamingResponseBody> downloadFile(
            HttpServletRequest request,
            @RequestParam String devSN,
            @RequestParam String downloadToken) {

        return appOrDataPackageService.download(devSN, downloadToken, request);
    }


    @ApiOperation("获取设备待执行任务接口")
    @GetMapping("/GetUpdate")
    public TaskMessage getPendingTasksOrder(
            @ApiParam(value = "设备SN编号", required = true, example = "DEV123456789")
            @NotBlank(message = "设备SN不能为空")
            @RequestParam String devSN) {

        // 去除前后空格
        devSN = devSN.trim();

        return pendingTaskService.getDeviceAllPendingTasksOrder(devSN);
    }

    /**
     * 任务执行结果接口,  设备每执行完一个事项,上报结果,成功还是失败,处理了 什么东西
     */

    //任务执行结束后上报给地面服务器
    @ApiOperation("上报任务进度")
    @PostMapping("/ISDT_To_Server_TASKRPT")
    public R taskResult( @RequestBody @Valid TaskStatusPost post) {

       log.info("任务执行进度: " + post);
        try {
            boolean result = interactionService.postDeviceTaskResults(post);
            if (result) {
                return R.ok("任务执行结果上报成功");
            } else {
                return R.fail("任务执行结果上报失败");
            }
        } catch (Exception e) {
            return R.fail("任务执行结果上报异常: " + e.getMessage());
        }
    }


 

    /**
     * 心跳包   设备每隔一段时间就上报状态信息->代注册
     * 如果设备已经登记过,则自动变为已注册已登记,设备可用
     * 如果设备未登记过,则状态为已注册已登记
     */

    @ApiOperation("代注册")
    @PostMapping("/ISDT_To_Server_DEVSTAT")
    public R heartbeat(@RequestBody  TbDeviceAndInfoCreateDTO dto) {
       logger.info("设备信息: " + dto);
        return interactionService.registrationAgent(dto);
    }

    /**
     * 下载离线包
     */
    @ApiOperation("下载离线包")
    @GetMapping("/download/offline/package")
    public ResponseEntity<Resource> downloadOfflinePackage(
            @RequestParam @NotBlank String packageVersioncode,
            @RequestParam @NotBlank String packageVersionnumber, // 修正了参数名拼写
            @RequestParam @NotNull Long packageId) throws IOException { // 移除了未使用的 HttpServletResponse

        File zipFile = null;
        boolean downloadSuccess = false; // 成功标志

        try {
            // 1. 生成离线包
            zipFile = offlinePackageService.generateOfflinePackage(packageVersioncode, packageVersionnumber, packageId);

            // 2. 生成文件名
            String filename = String.format("offline_package_%s_%d_%d.zip",
                    packageVersionnumber,
                    packageId,
                    System.currentTimeMillis());

            // 3. 构建响应实体
            ResponseEntity<Resource> response = ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"")
                    .contentType(MediaType.APPLICATION_OCTET_STREAM)
                    .contentLength(zipFile.length())
                    .body(new FileSystemResource(zipFile));

            downloadSuccess = true; // 标记成功，文件将由浏览器下载流式传输
            return response;

        } finally {
            // 4. 资源清理：只有在失败（未成功返回响应）或最终需要清理时才异步删除
            // 如果成功，文件将在流式传输后由异步任务删除。
            // 如果失败，立即安排删除。
            if (zipFile != null) {
                if (downloadSuccess) {
                    // 成功返回响应，启动延迟清理任务
                    asyncCleanupTempFile(zipFile);
                } else {
                    // 生成响应过程中出现异常，立即安排清理（无需长延迟）
                    asyncCleanupTempFile(zipFile, 0);
                }
            }
        }
    }

    /**
     * 异步清理临时文件（默认延迟30秒）
     */
    private void asyncCleanupTempFile(File zipFile) {
        asyncCleanupTempFile(zipFile, 30000); // 默认延迟30秒
    }

    /**
     * 异步清理临时文件（可指定延迟）
     * @param delayMillis 延迟毫秒数
     */
    private void asyncCleanupTempFile(File zipFile, long delayMillis) {
        CompletableFuture.runAsync(() -> {
            try {
                if (delayMillis > 0) {
                    Thread.sleep(delayMillis);
                }
                boolean deleted = offlinePackageService.cleanupTempFile(zipFile);
                if (!deleted) {
                    log.warn("临时文件删除失败: {}", zipFile.getAbsolutePath());
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                log.warn("文件清理任务被中断");
            }
        }).exceptionally(ex -> {
            log.warn("异步清理文件失败: {}", zipFile.getAbsolutePath(), ex);
            return null;
        });
    }
}
